#include "clientnet.h"
#include "../route/route.h"

ClientNet::ClientNet(QWidget *parent):QWidget(parent)
{

}

//静态变量的初始化必须定义在外面
ClientNet* ClientNet::singleObj = NULL;

ClientNet* ClientNet::NewInstance(){
    if(singleObj == NULL){
        singleObj = new ClientNet();
        singleObj->connectByQtSocket();
    }

    return singleObj;
}


bool ClientNet::connectByRawSocket(){
    this->connfd = 0;
    int sockfd, portno;
    struct sockaddr_in serv_addr;

    portno = ClientNet::PORT;

    //创建socket
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if(sockfd < 0){
        qDebug()<<"创建socket失败"<<endl;
        return false;
    }

    //准备connect
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_addr.s_addr = inet_addr(ClientNet::IP);
    serv_addr.sin_port = htons(portno);
    if(::connect(sockfd, (struct sockaddr*) &serv_addr, sizeof(serv_addr)) < 0){
        qDebug()<<"connect socket失败"<<endl;
        return false;
    }

    this->connfd = sockfd;

    return true;
}

//连接服务器
bool ClientNet::connectByQtSocket(){
    this->conn = new QTcpSocket();
    this->conn->connectToHost(ClientNet::IP, ClientNet::PORT);
    this->conn->setSocketOption(QAbstractSocket::LowDelayOption, 1);
    if(!this->conn->waitForConnected()){
        qDebug() << "连接失败" << endl;
        return false;
    }

    //注册槽函数，
    //@param1 被触发的对象
    //@param2 被触发的事件
    //@param3 信号处理的类
    //@param4 信号处理的函数
    connect(conn, &QTcpSocket::readyRead, this, &ClientNet::slotRecvMsg);
    return true;
}


//1、处理tcp的connect信号函数
//1.1、处理收到的消息由route解析出来，分配给各个interface
//2、
//2.1、异步接收到的回调函数也放在route里面，然后由route分配给各个interface
//2.2、ClientNet::sendMsg(std::string msg)为纯string，由model封装好之后传进来
//3、业务login,chat等
bool ClientNet::sendMsg(std::string msg){
    if(!this->conn->waitForConnected()){
        qDebug() << "连接已断开" << endl;
        return false;
    }

    int sendSize;
    sendSize = msg.length() + 1;
    if(sendSize > ClientNet::MAXBUFFER){
        char* str = new char;
        sprintf(str, "发送内容超过buffer， MAXBUFFER=%d, msg.length()=%d", ClientNet::MAXBUFFER, sendSize);
        qDebug() << str << endl;
    }

    qDebug() << "发送长度" << msg.length() << endl;
    qDebug() << "发送内容：" << msg.c_str() << endl;

    //使用发送定长MAXBUFFER来防止粘包
    int returnWriteNum = this->conn->write(msg.c_str(), ClientNet::MAXBUFFER);

    qDebug() << "确定发送长度：" << returnWriteNum << endl;

    return true;
}

void ClientNet::slotRecvMsg(){
    QByteArray buffer = this->conn->readAll();
    qDebug() << "接受消息：" << buffer << endl;
    Route* route = Route::NewInstance();
    route->distributeRecvMsg(buffer);
}
